#include "timer_wheel.hpp"
#include <iostream>
#include <chrono>
#include <thread>
#include <cassert>
#include <atomic>

using namespace timeout_manager;

// g++ -std=c++17 -pthread -o test_timer_wheel test_timer_wheel.cpp timer_wheel.cpp

// 用于测试的全局计数器
std::atomic<int> timeoutCounter(0);
std::atomic<int> callback1Counter(0);
std::atomic<int> callback2Counter(0);

void testBasicTimer() {
    std::cout << "\n=== 测试基本定时器功能 ===" << std::endl;
    
    // 创建一个小的时间轮便于测试（10个槽，每个槽100ms）
    TimerWheel wheel(10, std::chrono::milliseconds(1000));
    
    timeoutCounter.store(0);
    
    // 启动时间轮
    wheel.start();

    std::this_thread::sleep_for(std::chrono::seconds(2));
    
    // 添加一些定时任务
    wheel.addTimer(1, std::chrono::milliseconds(4500), []() {
        std::cout << "任务1超时！" << std::endl;
        timeoutCounter.fetch_add(1);
    });
    
    wheel.addTimer(2, std::chrono::milliseconds(6500), []() {
        std::cout << "任务2超时！" << std::endl;
        timeoutCounter.fetch_add(1);
    });
    
    wheel.addTimer(3, std::chrono::milliseconds(5500), []() {
        std::cout << "任务3超时！" << std::endl;
        timeoutCounter.fetch_add(1);
    });
    
    // 检查统计信息
    auto stats = wheel.getStatistics();
    std::cout << "添加任务后统计: 总槽数=" << stats.totalSlots 
              << ", 活跃定时器=" << stats.activeTimers << std::endl;
    wheel.printAllSlots(true, 0);
    wheel.printAllSlots(false, 2);
    
    // 等待任务执行
    std::cout << "等待定时任务触发..." << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(19000));
    
    // 验证结果
    std::cout << "超时任务执行次数: " << timeoutCounter.load() << std::endl;
    assert(timeoutCounter.load() == 3);
    std::cout << "✓ 所有定时任务都正确触发" << std::endl;
    
    wheel.stop();
}

void testRemoveTimer() {
    std::cout << "\n=== 测试删除定时器 ===" << std::endl;
    
    TimerWheel wheel(10, std::chrono::milliseconds(100));
    
    callback1Counter.store(0);
    callback2Counter.store(0);
    
    wheel.start();
    
    // 添加两个任务
    wheel.addTimer(10, std::chrono::milliseconds(300), []() {
        std::cout << "任务10不应该执行！" << std::endl;
        callback1Counter.fetch_add(1);
    });
    
    wheel.addTimer(20, std::chrono::milliseconds(400), []() {
        std::cout << "任务20应该执行" << std::endl;
        callback2Counter.fetch_add(1);
    });
    
    // 等待一小段时间
    std::this_thread::sleep_for(std::chrono::milliseconds(50));
    
    // 删除第一个任务
    bool removed = wheel.removeTimer(10);
    assert(removed);
    std::cout << "✓ 成功删除任务10" << std::endl;
    
    // 尝试删除不存在的任务
    bool notRemoved = wheel.removeTimer(999);
    assert(!notRemoved);
    std::cout << "✓ 正确处理删除不存在的任务" << std::endl;
    
    // 等待剩余任务执行
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    
    // 验证结果
    assert(callback1Counter.load() == 0);  // 任务10不应该执行
    assert(callback2Counter.load() == 1);  // 任务20应该执行
    std::cout << "✓ 删除功能工作正常" << std::endl;
    
    wheel.stop();
}

void testExceptionInCallback() {
    std::cout << "\n=== 测试回调函数异常处理 ===" << std::endl;
    
    TimerWheel wheel(10, std::chrono::milliseconds(100));
    
    std::atomic<bool> normalTaskExecuted(false);
    
    wheel.start();
    
    // 添加一个会抛出异常的任务
    wheel.addTimer(100, std::chrono::milliseconds(150), []() {
        std::cout << "即将抛出异常的任务" << std::endl;
        throw std::runtime_error("测试异常");
    });
    
    // 添加一个正常任务，确保时间轮在异常后仍能工作
    wheel.addTimer(200, std::chrono::milliseconds(350), [&normalTaskExecuted]() {
        std::cout << "正常任务执行" << std::endl;
        normalTaskExecuted.store(true);
    });
    
    // 等待任务执行
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    
    // 验证正常任务仍然执行了
    assert(normalTaskExecuted.load());
    std::cout << "✓ 异常处理正常，时间轮继续工作" << std::endl;
    
    wheel.stop();
}

int main() {
    std::cout << "开始测试时间轮..." << std::endl;
    
    testBasicTimer();
    testRemoveTimer();
    testExceptionInCallback();
    
    std::cout << "\n所有时间轮测试通过！" << std::endl;
    return 0;
}